package md.specialEqp.inspect;

import com.querydsl.core.annotations.QueryInit;
import graphql.schema.DataFetchingEnvironment;
import lombok.*;
import md.cm.unit.Unit;
import md.specialEqp.fee.Charging;
import md.specialEqp.type.PipingUnit;
import org.fjsei.yewu.filter.Node;
import org.fjsei.yewu.filter.Uunode;
import org.fjsei.yewu.pojo.SliceSyncRes;
import org.fjsei.yewu.util.Tool;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.search.engine.backend.types.Aggregable;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField;

import jakarta.persistence.*;
import jakarta.validation.constraints.Size;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

//物理上分表模式:使用类一级的 @SecondaryTable或@SecondaryTables注解可以实现单个实体到多个表的映射;使用@Column或者@JoinColumn注解中的table参数可指定某个列所属的特定表.
//将实体映射成多个表 { @Column(table = "detail", name = "xx") }; 一个Entity映射成1个主表+N个从表; #但是不够灵活：整个Entity都一样必须有数据,不能舍弃不存储。@SecondaryTable(name = "", pkJoinColumns = @PrimaryKeyJoinColumn(name = ""))

/**类似Isp，但是仅仅保留处于活动状态的业务信息。属于Isp的一小部分，但是存储字段是Isp没有的信息。
 * 检验信息, 业务信息设置: 检验Isp相关的热数据部分。Isp+Report+收费对象属于归档长久存储的，而Details的字段属于短期存储的。
 * Detail的物理数据库表中没有直接字段配置Eqp的，通过isp.dev来访问/java.graphQL实际可搞名义伪字段短接到Eqp。
 * 扩展 业务记录细节， 监检或定期检验等的或甚至检测工作情况。替换Isp位置。 热数据Detail必须有,冷数据Detail就没有。
 * 一般地，EQP有的字段就没必要复制一份放在这里了，多数业务都能直接用eqp字段取值。
 * 水质报告 安全阀 制造报告 的定位标志。
 * 检验现场每一次检验都会变动的 其余字段。
 * Isp是报告编号查询主入口：冷热数据分离方式之一： 扩充的字段，检验业务工作细节表。
 * 有些字段应该算作业务扩展信息：单独扩展检验数据实体 可针对特定设备的 在检验时间才获得数据。
 * 收费参数选择的-进入Detail也能自动计算收费依据{太多字段？物理扩充表@SecondaryTables},按照业务设备类型共享字段=压缩。
 * Detail取代Isp模型位置，前端路由还是 *-/isp/-* 的。Isp模型精简的=历史报告入口；Detail是全量字段的，但数据保存时间没有Isp长。
 * 【性能需求】可能因为@OneToOne Isp的牵扯：对于@OneToMany字段的多端那一个表，必须建立非唯一性的索引@Index(columnList = "task_id",unique=false)；否则就算多端Detail实际记录数很少的，导致实际上按照Isp记录数量做全表匹配，运行很慢。
 */

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder(toBuilder=true)
@Entity
@Table(indexes={
        @Index(name="detail_task_id_idx",columnList = "task_id",unique=false)
    }
)
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "Fast")
public class Detail implements Uunode,SliceSyncRes {
    @KeywordField(aggregable = Aggregable.YES)
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID id;
    //【注意问题】因为缓存存在滞后，在别的途径更新的type数值随后在缓存未更新时间之内可能被恢复回去的。 #乐观锁 并发控制#
    //可以确保提示前端存在冲突报错(数据库层JPA层?报错)，后端底层可以自动更新已被其它渠道修改的缓存字段，前端再次点击保存就可以使得正常。
    @Version
    private int  version;
    //若需要双向的1 ：1关系，关系是Unit类维护； 就把下面俩个行添加上。 太多了？很多的业务很多模块插入关联关系字段？
    /**配对Isp；有必要的： 方便反向关联。 isp不能=null
     * 业务Detail没有直接关联Eqp，通过Isp接力; Isp/报告存档#是永久存储性质的， Detail和Task都是热点数据有较短保存期限的。
     * 实际在Isp物理表的字段bus_id来关联;   #有性能问题：Isp表记录多导致数据库也认定Detail记录数也会多的；sql自动优化有问题。?难道数据库背黑锅？？
     * 1个Task->Detail(多个) =》Isp :: EQP(单一个设备、或没有设备台账的检验报告)； Isp尽量精简的字段，EQP都是固定设备而不是每一次检验都不同的信息。
     * 所以监检若要 (结构化)加 “告知日期” 监察许可链接的就得加到这里的:到监察提交材料后获准准生证（许可施工）凭证回执单：链接或书面盖章来拍照上传，会是一组设备都对应同一个告知单的#。
     * 监察和检验的互动？告知单那些设备获得许可施工了？ 只需检验员人工核查：没证不能检验：没有事务严谨性，可信任作单方面证实。
     * */
    @QueryInit({"report.stm.master", "dev.ad"})
    @OneToOne(mappedBy = "bus")
    private Isp  isp;

    /**设备种类 EQP_TYPE；不一定要设置的。 若type+isp.dev都设置设备种类的话就该以这个设置优先。
     * 单独的水质、安全阀报告 或 制造监检的： 假如跟随的Isp.dev不是null的就不能设置该字段了；
     * 关联设备的检验: 该字段最好=null。
     * 对于Vessel子类可有两个type=‘2’||‘R’=目录外的常压容器;
     * "F" 安全阀
     * "Z" 水质
     * "7" 压力管道元件 制造质量监督检验
     * */
    @Column(nullable = true)
    @Size(min = 1)
    private String type;
    @Column(nullable = true)
    @Size(min = 2, max = 2)
    private String sort;
    @Column(nullable = true)
    @Size(min = 3, max = 3)
    private String vart;

    /**报告附加标识，有Eqp台账的就没必要设置;
     * 对于无设备台账的业务：方便在1个Task当中区分不同的Isp业务：报告编号也能区分；最好能直接写上安装位置，设备出厂编码，设备型号等。
     *用户侧附加标识：给用户做报告查询时刻区分标注用的。 制造监检除了检验日期之外的需附加上批次标识，制造监检批准证书编号之外的辨识。
     * */
    private String  ident;

    /**任务很可能已经过期或清理掉，历史数据。
     * 单个检验记录规属于某一个TASK底下的某次; 单一个设备执行多次作业活动要跑很多趟的，很多人不同场次做的作业的，当成一次。
     一个任务单Task包含了多个的ISP检验记录。 　任务1：检验N；
     同一个Task底下每个Eqp不能重复保证唯一性，没有挂接Eqp的？只能最多一条Isp;
     //我是多的方，我是维护关系，保存必须设置我！我方表字段包含了对方表记录ID
     父Task若是拆分，就变更挂接到新的Task,多个Isp其中有部分Eqp不合格，可允许Task拆分独立终结;
     必须有： task！=null。
     */
    @QueryInit({"servu" })
    @ManyToOne(fetch= FetchType.LAZY)
    @JoinColumn(name = "task_id")
    private Task task;

    /**收费确认了吗？
     * 涉及到了mod1各项目收费的参数被修改的直接作废未终结任务的Isp的收费依据。重置收费确认标记。管道单元有涉及Task的。
     * 取消确认，再次修改和计算。
     * 受到任务影响，可能会被迫取消确认状态！
     */
    @Builder.Default
    private boolean  feeOk=false;
    /**业务服务最终应该 收的收费额  >=0； 单个Isp/Detail收钱。
     * 单一个Isp的；  Task.x==合计应该收费/多台Isp有可能还有折扣。
     * 一个任务Task底下有多条Detail-Isp业务：Task层面需要汇总任务级收费。任务级收费==多个Isp业务报告级收费的合计+折扣。
     * */
    private Double  sprice;

    /**多条收费，清单。 说明理由来自各个条目：
     * 收费跟随Detail，若业务退化成了历史冷数据只剩下Isp报告信息的，收费数据也就擦除。
     * orphanRemoval: 多方即对方在一行被删除时刻也会白主动删除掉的(即使没有配cascade也会删); 收费明细附 属于 Detail设备某次业务单。
     */
    @Builder.Default
    @OneToMany(mappedBy = "detail",orphanRemoval=true)
    @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL,region ="Fast")
    private List<Charging>  fees=new ArrayList<>();

    /**选定涉及范围的单元： 派工环节末尾，或检验工作初始化步骤的。必须属于同一个管道装置PipeLine对象模型。
     * 本检验的全部单元，@注意Charging计费里面又有另外配置单元的字段=不能替代本字段：我这里是全部的计费那里是部分单元。
     * 这里又会和检验原始记录录入也就是PDF初始化选定管道单元的环节冲突？一致性呢：本次检验初始化选定单元环节，影响到计费环节。
     * */
    //若删除本条detail，PipingUnit也需要将关联的id字段清空
    //加载方式修改影响很大。根据业务场景挑选。懒加载了若想关联内省查询会运行错误。管道单元业务锁;
     //实际关联表detail_pipinguint只有dets_id + pipus_id两个字段的。
//    @OneToMany(mappedBy = "det")
    @ManyToMany
    @JoinTable
    @ToString.Exclude
    @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL,region ="Fast")
    private List<PipingUnit>  pipus;


    /* 扩展EQP字段没有的信息：
      */
    //需要长期保留的字段内容：冷Isp数据都会要出保存的部分字段；isp1,isp2,ispsv没有关联得到的冷数据Isp,转移存储的冷数据库表配套专门的查询接口页面。
    //需要长期保留的字段内容：但是移入冷Isp数据之后就会被丢弃的字段。
    //不需要长期存储的字段内容：检验Task期限之内有用到的字段，随着报告任务结束就可以丢弃的字段？||和Isp关联 pk 和Task关联？。

    /**复检次数 选择参数：继承=复检次数; 第一次复检=1,...  默认是0
     * 是复检任务的 recnt>=1
     * 默认是非NULL比较好，理由：
     * （1）可以大大的节省存储空间，因为当某一列设为default null时，数据库需要用额外的一个字节记录每条record是否为null
     * （2）很多操作，如order by、group by等都会忽略值为NULL的record;
     * */
    //@Column(nullable=false, columnDefinition="tinyint unsigned default 0") MySQL;小强DB最少2字节
    @Builder.Default
    private Short  recnt=0;

    /**施工工程费; (元)
     * 单台工程施工费（单位: 元） TB_TASK_MGE.INST_PRICE
     * 注意：单位从万元 修改成 单位: 元
     * 1000 : OPE_TYPE":"13" : 化学清洗工程费;
     * */
    private Float ccost;
    /**改造、修理的 设备价(元)，代替固定的EQP_PRICE ；直接用Eqp.money不适合此场景。
     * 3000 +OPE_TYPE":"14,15" 情况：用它替换Eqp.money用于计费目的;modified repair equipment PRICE
     * */
    private Float  mreprc;

    /**制造产品设备价:
     * 3000 制造监检验 单台设备价；
     * 1000 工业锅炉制造过程监督检验受检产品设备价
     * F000 OPE_TYPE":"4": 安全阀+进口安全性能监督检验--产品设备价;
     * 7000 OPE_TYPE":"1"  压力管道元件制造质量监督检验 -产品设备价
     * 2000容器 制造:
     * 6000 大型游乐设施制造过程监督检验 游乐设督施单台设备价;
     * */
    private Double  zmoney;


    /**非现场复检 选择参数：复检无需现场复检确认;    默认是要去现场
     * */
    //@Column(nullable=false, columnDefinition="bit(1) default b'0'") 不会上null状态所以不用Boolean定义 .nsite(Boolean.TRUE.equals(in.getNsite())); MySQL尽量避免NULL，指定列NOT NULL
    @Builder.Default
    @Column(nullable=false)
    private Boolean nsite=false;

    /** 5000 厂车是否工作装置测试'   IF_WORKEQP_TEST==是||IF_WORKEQP_TEST==1
     *  4000 起重：是否载荷试验'  TB_TASK_MGE.IF_HOLD_TEST, OPE_TYPE":"2,14,15,16"
     *  F000 +OPE_TYPE":"13"："使用安全阀在线检测仪进行安全阀在线排放试验，按安全阀在线校验费的20%收费""EXTRAFEE_ID":"103"
     * */
    @Builder.Default
    private boolean test=false;
    /**4000 派生自业务 便宜的那些。
     * 4000 起重机械安全监控管理系统试验派生自定期检验而非监督检验或者首检吗?     @ope_type=2||14||15||16;  @定检=3; 报告还区分委托/法定;
     *          / 业务派生来源于:定期检验 ？？实际上属于配置矛盾了。 原意是:"定期检验是600元;其它/首检都是1500元"？
     * 1000 +OPE_TYPE":"19"： 热效率测试 简单测试的 而不是详细测试；  缺省=热效率详细测试
     * F000 +OPE_TYPE":"13"："采用实跳方式进行安全阀在线校验的，收费标准下浮50%","EXTRAFEE_ID":"105"
     * */
    @Builder.Default
    private boolean cheap=false;      //缺省值取的是 收钱价格高的。
    //改成boolean类型缺省就是不可null的； 而 Boolean才允许null字段。
    //bit(1)类型占用的空间与BIT类型的列所在表的位置有关，有些情况下BIT占用了一个字节，有些情况下BIT实际占用了几个位。
    /** 1000 +OPE_TYPE":"19"： 是否 工业锅炉定型产品热效率测试;
     *  F000 +OPE_TYPE":"13"："检验机构到使用单位进行离线安全阀校验的，校验费上浮50%","EXTRAFEE_ID":"99"
     * */
    @Builder.Default
    private boolean  apprp=false;

    /** F000 +OPE_TYPE":"13"： 是否 在线校验（收费贵，较少）的,而不是离线校验的; @派工必须让前端选择在线或离线！
     * */
    @Builder.Default
    private boolean  online=false;
    /** F000 +OPE_TYPE":"13"： 进口安全阀在线校验按标准收费的200%收取","EXTRAFEE_ID":"100"
     * */
    @Builder.Default
    private boolean  impor=false;

    //不用@Column(nullable=false, columnDefinition="bit(1) default b'0'")缺省值会是false的，不会认@Builder.Default缺省值。两个机制归属层次，一个DB库层一个JPA层。
    /** F000 +OPE_TYPE":"13"： "对安全阀密封面直径进行现场检测计算的，按安全阀在线校验费的20%收取","EXTRAFEE_ID":"102"
     * R000 +OPE_TYPE: "608" 常压容器 =不要开启"气密性试验"的项目收费; 没有气密性试验的收费:
     * 2000 +OPE_TYPE":"3,8" + "221".equals(vart) || "222".equals(vart) || "224".equals(vart) || "223".equals(vart) || "225".equals(vart) : 不要开启"气密性试验"的项目收费;
     * */
    @Builder.Default
    @Column(nullable=false)
    private Boolean ntscop=false;

    /**承压类: 进口承压类特种设备安全性能监督检验的设备品类：{都是前端输入的，但并非是人工选择手选模式的那些}
     * 直接让前端录入 FEE_COD，人工选择判定分支 ,保障fee_mod=1都是自动计算的。
     * "进口承压类特种设备安全性能监督检验收费标准" FEE_COD":"J000" OPE_TYPE":"4" 合格产品9个分支 不合格产品7个分支 OPE_TYPE EQP_TYPE过滤后的。
     * 1000 锅炉：OPE_TYPE":"4"  前端可选择 3+3 个收费码；
     * F000 安全阀  OPE_TYPE":"4":  1+1条收费码;
     * 2000 容器： OPE_TYPE":"4":  9条收费码；“合格产品”5条 +“不合格产品”4条；
     * 容器+特别合并(不是进口安全性能检验)：
     * 2000 容器： OPE_TYPE":"1"制造监检 && EQP_SORT==2300:  4条收费码；
    * */
    private String  fcode;

    //是否使用年限到期了 IF_USE_OVERYEAR 是否使用年限到期
    //如何断定设置的/批量初始化、检验触发的？【日期+预期寿命】 是否老旧电梯：IF_OLD_DT 是否老旧电梯评估 IF_OLDDED_DT_PG
    //是否老旧电梯：IF_OLD_DT 是否老旧电梯评估 IF_OLDDED_DT_PG_q 检验历史上做了，延长EXTEND_USE_YEAR?或判定不合格/改造大修;


    /**CONS_UNIT "施工单位";土建施工单位 检验的报告才用到的；
     * 编制检验报告，要选择配套的施工单位。
     * BUILD_UNT_ID 业务申请中的施工单位 (监检)安装|改造|维修的融合称谓，SDN用的BUILD_UNT_ID，监察施工告知用；
     * 类似字段 Eqp.svp.土建施工单位:
     * [!]$施工单位 BUILD_UNT_ID BUILD_UNT_NAME；?施工告知Isp的+申请的任务？不应该放Eqp.底下,挂接错配?=>修改了改造维修安装单位?
     * */
    @Deprecated
    @ManyToOne(fetch= FetchType.LAZY)
    @JoinColumn
    private Unit constu;

    //"IF_PARAM"监察没有字段；Eqp.IF_PARAM第一位，是否限速器校验(1-5杂物电梯5进制)?=0,'1',任务生成? IF_PARAM = '1'表示需要限速器校验。
    //Eqp."ISP_TYPE""检验范畴 1:机电，2：承压，3：综合" Eqp.仅"22" Eqp内部作废？ 牵涉收费条目、部门归属/会计;
    //IF_OTHERREREP  '已报检';
    //LAST_GET_DATE 更新发证日期
    //FS_EQP_COD 起重机械附属装置设备信息 TB_CRANE_UNIT;
    //COR_DATE 整改反馈日期 如果复检派工的时间小于等待整改反馈期，则取原来的报告号TO_CHAR(A.COR_DATE, 'yyyy-mm-dd') >= TO_CHAR(SYSDATE, 'yyyy-mm-dd')\n")
    //  '超期未整改'  机电类安装监检报告，首检报告，检验结论为不合格的，因报告中没有记录整改反馈日期，

    //EFF_DATE下次定检日期; INP_BEG_DATE监检开始日期
    //IF_BATCHMAKE 制造监检 按批出具的压力容器数量TB_ISP_INSPSTOP_MGE.EQP_NUM|TB_ISP_MGE.EQP_NUM;
    //EQP_NUM  制造 压力容器数量
    //CURR_NODE,OPE_TYPE,ISP_TYPE机电1,BUSI_TYPE法定1；

    //ASSINV_FALG 0,1,2,3发票关联状态非法 发票关联及审核标志 0未关联1关联未审核2关联已审核;
    // ? 如果有关联检验合同，且为制造监检 则无需关联收费清单;
    //TASKFEE_FALG 收费审核标志 -1=未查看过收费清单,
    //ISP_CONCLU
    //F_GET_TASKFEEBYTASKID(A.TASK_ID, 0) PRICE_CNT 报告是否有收费清单标志
    //  报告收费清单状态,F_GET_TASKFEEBYTASKID(A.TASK_ID, 1) PRICE_TOTAL 报告收费清单金额;
    //LIMIT_UPLOAD_TYPE 作废字段？承压类如果是不合格数据，必须选择问题类型

    /**计费乘数 内外部检验面积
     * 2000 +"EQP_VART==2210||EQP_VART==2220||EQP_VART==2240||EQP_VART==2230||EQP_VART==2250";+OPE_TYPE":"3，8" 情况： 内外表面检验 平方米 FEE_COD":"2610",
     * R000 +OPE_TYPE: "608" 常压容器 "内外部检验" FEE_COD":"Q310"
     *  */
    @Builder.Default
    //@Column(nullable=false)
    private Float  varea=0f;

    //MySQL中存储null的确为额外占用一些空间，但将列从null优化为not null，并非会有性能提升。null的问题主要还是一些逻辑方面的问题 (A!=X OR A is null);
    /**F000 OPE_TYPE":"13" : WORK_PRESS 工作压力。 公称压力Pg≤1.6 MPa的; 安全阀没有设备台账，很多字段需要临时做业务设置的。
     * */
    private Float  opprn;
    /**2000 OPE_TYPE":"3,8" 液面计、紧急切断阀及其它附件检验" 合计收费金额  FEE_COD":"2660"，"30~60", 元/只
     * R000 +OPE_TYPE: "608" 常压容器  "其他附件检查" 收费金额  Q350",
     * */
    @Builder.Default
    //@Column(nullable=false)
    private Float  totm=0f;
    /**F000 OPE_TYPE":"13" : GC_CALIBER 公称通径 DN,规格mm。
     * 2000 OPE_TYPE":"3,8"  "耐压试验" 乘数 立方米 FEE_COD":"2620"; 气密性试验 耐压试验的两个立方米 还不一样，耐压试验数据!=台账的容积。
     * R000 +OPE_TYPE: "608" 常压容器  "水压试验"  Q320", 乘数 m3
     * */
    private Float  diame;
    //加上@Column(nullable=false)没好处？接口函数更新时刻必须给出数值,否则报错; null判定还是挪到末端代码去更加恰当。mySql字段允许null; 可空不可空两种模式处理完全不同。
    /**2000 OPE_TYPE":"3,8"  除锈喷漆" 乘数 平方米 FEE_COD":"2640"
     * R000 +OPE_TYPE: "608" 常压容器  "盛水试验"  Q370" 乘数 m3
     * 1000 +OPE_TYPE":"1"  锅炉 制造监检 RATCONS 额定功率(MW)/蒸发量=gn
     * */
    private Float  rustc;

    //columnDefinition="tinyint unsigned default 0"  无符号的范围是0到255; Byte是带符号的MAX_VALUE=127;
    //@Unsigned注解似乎？ 设置不成功;  Java 中没有定义 unsigned 类型，Java不带符号的移位操作 >>>
    /**Z000 OPE_TYPE:"11" "浊度" FEE_COD":"S110"
     * Z000 OPE_TYPE:"12" "运动黏度" FEE_COD":"T110"
     * */
    @Builder.Default
   // @Unsigned
  //  @Column(nullable=false)
    private Byte turbi=0;
    /**Z000 OPE_TYPE:"11" "硬度"  "S120"
     * Z000 OPE_TYPE:"12" "密度"  8,
     * */
    private  Byte hardd;

    /**Z000 OPE_TYPE:"11" "PH值"  S130"
     * Z000 OPE_TYPE:"12" "水溶性酸碱"  7,
     * */
    private Byte  phval;
    /**Z000 OPE_TYPE:"11" "电导率"  4,
     * Z000 OPE_TYPE:"12" "闭口闪点"  4,
     * */
    //@Builder.Default
    //@Column(nullable=false, columnDefinition="tinyint unsigned default 0")
    private Byte  conduc;
    /**Z000 OPE_TYPE":"11",锅炉水质  "酚酞碱度" 5,
     * */
    //@Builder.Default  ##改成nullable=true更适合？，null可在接口或逻辑等处解决；SQL查询比较过滤和索引也不较少牵涉本字段。
    //@Column(nullable=false, columnDefinition="tinyint unsigned default 0")
    private Byte  palka;
    /**Z000 OPE_TYPE":"11", "全碱度（总碱度）"  6,
     * */
    private Byte  totalk;
    /**Z000 OPE_TYPE":"11", "溶解固形物"  7,
     * */
    private Byte  dsolid;
    /**Z000 OPE_TYPE:"11" "磷酸根" 8,
     * Z000 OPE_TYPE:"12" "酸值"  "T120",
     * */
    private Byte  phosph;
    /**Z000 OPE_TYPE:"11" "油"  9,
     * Z000 OPE_TYPE:"12" "水分"   5,
     * */
    private Byte  oilw;
    /**Z000 OPE_TYPE":"11", "全铁" "S1A0",
     * */
    @Builder.Default
    @Column(nullable=false)
    private Byte  tiron=0;
    /**Z000 OPE_TYPE":"11", "亚硫酸根"  B,
     * */
    private Byte  sulfit;
    //mySql数据库层次报错：不可null字段，com.mysql.cj.jdbc.exceptions.SQLError. 报错点更加底层；
    /**Z000 OPE_TYPE":"11", "相对碱度" "S1C0"
     * */
    private Byte  rebasi;
    /**Z000 OPE_TYPE":"11", "氯离子"  D,
     * */
    private Byte  chrion;
    /**Z000 OPE_TYPE":"11", "溶解氧"  E,
     * */
    private Byte  dioxy;
    /**Z000 OPE_TYPE:"11" "水垢全分析" F,
     * Z000 OPE_TYPE:"12" "残炭"   130",
     * */
    //@Column(nullable=false, columnDefinition="tinyint unsigned default 0")
    private Byte  carbon;
    /**Z000 OPE_TYPE:"11" "树脂交换容量分析" FEE_COD":"S1G0"
     * Z000 OPE_TYPE:"12" "5%低沸物馏出温度"  6,
     * */
    private Byte  captem;

    /**2000 OPE_TYPE":"3,8"  安全阀性能试验 -乘数 多少只
     * R000 +OPE_TYPE: "608" 常压容器  "导静电测试"  FEE_COD":"Q360" -乘数 *次数
     * */
    private Short  num;
    /**2000 OPE_TYPE":"3,8"  液面计、紧急切断阀及其它附件检验 -乘数 =多少只
     * R000 +OPE_TYPE: "608" 常压容器  "通气阀性能试验"  Q340, 乘数 =*只
     * */
    private Short  isum;

    /**计费参考度量数  容器检验部位总米数；
     * 2000 +OPE_TYPE":"3"情况：总米数: 容器检验部位>=6m,容器检验部位>=8m时 ; EXTRAFEE_ID":"96"
     * */
    private Double  meter;
    //批处理作业的日志
    private String  fail;

    /**type短接，给graphQL模型提供的专用，java后端尽量不用；
     * 前端graphQL接口的字段Detail.type直接读取这个函数，映射接口函数时顺序优先于this.type的Getter this.getType()；
     * */
    @Transient
    public String getType(DataFetchingEnvironment env){
        if(null!=isp && null!=isp.getDev())
            return isp.getDev().getType();
        else
            return this.type;
    }

}


/* @数据库修改脚本：
CREATE INDEX detail_task_id_idx ON public.detail USING btree (task_id ASC) STORING (apprp, captem, carbon, ccost, cheap, chrion, conduc, diame, dioxy, dsolid, fcode, feeok, hardd, ident, impor, isum, meter, mreprc, nsite, ntscop, num, oilw, online, opprn, palka, phosph, phval, rebasi, recnt, rustc, sprice, sulfit, test, tiron, totalk, totm, turbi, type, varea, version, zmoney, constu_id);
    遗留操作生成字段要删除：
alter table public.detail  drop column tisp_id;
* */
